<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Vosk 流式语音识别测试</title>
</head>
<body>
<h1>流式语音识别测试</h1>
<style>
  .status-badge {
    padding: 8px 15px;
    border-radius: 20px;
    font-weight: bold;
    font-size: 14px;
    color: white;
    transition: all 0.3s ease;
  }
  .btn {
    padding: 10px 20px;
    margin: 0 5px;
    border: none;
    border-radius: 5px;
    background: #4a6baf;
    color: white;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.3s ease;
  }
  .btn:hover {
    background: #3a5a9f;
    transform: translateY(-2px);
  }
  .btn:disabled {
    background: #cccccc;
    cursor: not-allowed;
  }
</style>

<div id="status-bar" style="margin-bottom: 20px; display: flex; align-items: center; gap: 10px;">
  <span id="connection-status" class="status-badge" style="background: #6c757d;">未连接</span>
  <span id="recording-status" class="status-badge" style="background: #6c757d;">未录音</span>
  <span id="connection-id" class="status-badge" style="background: #17a2b8;">ID: -</span>
</div>
<button class="btn" onclick="connect()">连接</button>
  <button class="btn" onclick="disconnect()">断开</button>
  <button class="btn" onclick="start()">开始</button>
  <button class="btn" onclick="stop()">停止</button>
<pre id="result" style="border: 1px solid #000; padding: 10px; border-radius: 5px;"></pre>

<script>
    let socket;
     let connectionId = '';
    const resultDiv = document.getElementById('result');

    function connect() {
      // 清空历史记录
      document.getElementById('result').innerHTML = '';

      socket = new WebSocket("ws://localhost:8080/stream");
      socket.onopen = () => {
         console.log("已连接");
         document.getElementById('connection-status').textContent = '已连接';
         document.getElementById('connection-status').style.background = '#28a745';
         connectionId = socket.url.split('/').pop();
         document.getElementById('connection-id').textContent = 'ID: ' + connectionId;
       };
      socket.onmessage = function(event) {
        resultDiv.textContent += event.data + "\n";
      };
    }

    function start() {
      document.getElementById('recording-status').textContent = '录音中';
       document.getElementById('recording-status').style.background = '#dc3545';
      startRecording();
      socket.send("start");
    }

    function stop() {
       document.getElementById('recording-status').textContent = '未录音';
       document.getElementById('recording-status').style.background = '#6c757d';
       stopRecording();
       socket.send("end");
     }
     
     function disconnect() {
       if (socket) {
         socket.close();
         document.getElementById('connection-status').textContent = '未连接';
          document.getElementById('connection-status').style.background = '#6c757d';
          document.getElementById('connection-id').textContent = 'ID: -';
       }
     }


    let mediaStream;
    let audioContext;
    let processor;

    function startRecording() {
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
          mediaStream = stream;
          audioContext = new AudioContext();
          const source = audioContext.createMediaStreamSource(stream);
          processor = audioContext.createScriptProcessor(4096, 1, 1);

          processor.onaudioprocess = e => {
            const audioData = e.inputBuffer.getChannelData(0);
            sendAudio(audioData);
          };
          
          source.connect(processor);
          processor.connect(audioContext.destination);
        })
        .catch(err => console.error('Error accessing microphone:', err));
    }
    
    function stopRecording() {
      if (mediaStream) {
        mediaStream.getTracks().forEach(track => track.stop());
      }
      if (audioContext) {
        audioContext.close();
      }
    }
    
    function sendAudio(data) {
      if (socket && socket.readyState === WebSocket.OPEN) {
        // 将Float32Array转换为Int16Array
        const int16Data = new Int16Array(data.length);
        for (let i = 0; i < data.length; i++) {
          int16Data[i] = Math.min(32767, Math.max(-32768, data[i] * 32767));
        }
        socket.send(int16Data.buffer);
      }
    }
</script>
</body>
</html>